package com.itheima.reggie.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.common.ResultInfo;
import com.itheima.reggie.domain.Category;
import com.itheima.reggie.domain.Dish;
import com.itheima.reggie.domain.DishFlavor;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishFlavorMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

//菜品管理
@Service
@Transactional
@Slf4j
public class DishServiceImpl implements DishService {
    //菜品注入
    @Autowired
    private DishMapper dishMapper;
    //风味注入
    @Autowired
    private DishFlavorMapper dishFlavorMapper;
    //分类注入
    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    //分页条件查询
    @Override
    public Page<Dish> findByPage(Integer pageNum, Integer pageSize, String name) {
        //构建菜品条件
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();//根据菜品名称查询
        qw.like(StrUtil.isNotEmpty(name), Dish::getName, name);//判断名称不等于空且不为空字符串，通过传入的name查找表中的名称
        //构建分页
        Page<Dish> page = new Page<>(pageNum, pageSize);//传入分页起始页和分页个数
        //查询分页
        page = dishMapper.selectPage(page, qw);//传入分页条件和查询条件
        //遍历菜品list集合
        List<Dish> dishList = page.getRecords();
        for (Dish dish : dishList) {
            //查询口味
            //构建口味条件
            LambdaQueryWrapper<DishFlavor> dqw = new LambdaQueryWrapper<>();
            dqw.eq(DishFlavor::getDishId, dish.getId());//通过菜品表id查询口味表id
            //查询口味列表
            List<DishFlavor> flavorList = dishFlavorMapper.selectList(dqw);//口味属多个，使用多个条件
            //封装到菜品实体类
            dish.setFlavors(flavorList);
            //查询分类
            Category category = categoryMapper.selectById(dish.getCategoryId());//通过菜品表id查询到分类表id
            dish.setCategoryName(category.getName());
        }
        //返回分页对象
        return page;
    }

    //新增菜品
    @Override
    public void save(Dish dish) {
        //新增之前的id
        log.info("新增之前id：{}", dish.getId());
        dishMapper.insert(dish);//传入前端接受信息并保存
        //添加之后的id
        log.info("新增之后id：{}", dish.getId());//新增之前id为空，添加成功后,主键返回
        //获取遍历传入的口味
        List<DishFlavor> flavorList = dish.getFlavors();
        for (DishFlavor flavor : flavorList) {
            flavor.setDishId(dish.getId());//口味关联菜品的id
            dishFlavorMapper.insert(flavor);//保存数据库
        }
        //清理该菜品所属分类缓存
        String dishKey = "dish:"+dish.getCategoryId();
        redisTemplate.delete(dishKey);//删除redis中数据；
    }


    //修改：菜品回显
    @Override
    public Dish findById(Long id) {
        //根据传入id查询菜品基本信息（主键直接查询）
        Dish dish = dishMapper.selectById(id);
        //查询口味信息
        LambdaQueryWrapper<DishFlavor> qw = new LambdaQueryWrapper<>();
        qw.eq(DishFlavor::getDishId, id);//根据传入的菜品id查询口味的id
        List<DishFlavor> flavorList = dishFlavorMapper.selectList(qw);//将查询到的口味封装
        dish.setFlavors(flavorList);//将口味设置到菜品
        //返回菜品回显
        return dish;
    }

    //菜品修改
    @Override
    public void update(Dish dish) {
        //修改传入的菜品信息
        dishMapper.updateById(dish);
        //先删旧口味
        LambdaQueryWrapper<DishFlavor> qw = new LambdaQueryWrapper<>();
        qw.eq(DishFlavor::getDishId, dish.getId());//通过菜品的id查询口味
        //删除查询到的口味
        dishFlavorMapper.delete(qw);
        //遍历输入的新口味
        List<DishFlavor> flavorList = dish.getFlavors();
        for (DishFlavor flavor : flavorList) {
            flavor.setDishId(dish.getId());//新口味关联菜品的id
            dishFlavorMapper.insert(flavor);//传入口味数据
        }
        //清除该菜品相关的缓存
        Set dishKeys = redisTemplate.keys("dish:*");//读取所有key
        redisTemplate.delete(dishKeys);//批量删除
    }

    //起售停售
    @Override
    public void updateStatus(Integer status, List<Long> ids) {
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        //根据传入的id查询菜品
        qw.in(Dish::getId, ids);
        //创建菜品对象的实体类
        Dish dish = new Dish();
        //传入的数据设置到数据库
        dish.setStatus(status);
        //将修改的数值传入dish表中的status数据值
        dishMapper.update(dish, qw);
        //清除该菜品相关的缓存
        Set dishKeys = redisTemplate.keys("dish:*");//读取所有key
        redisTemplate.delete(dishKeys);//批量删除
    }

    //菜品删除
    @Override
    public void deleteBatchIds(List<Long> ids) {
        //删除菜品
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        //通过传入的参数查询表中id
        qw.in(Dish::getId, ids);
        //判断表中的status状态是否停售
        qw.eq(Dish::getStatus, 1);
        Integer count = dishMapper.selectCount(qw);
        if (count > 0) {//判断查询统计数量不为0的菜品就不能删除
            throw new CustomException("删除的菜品状态必须为已停售！~~");
        }
        //通过传入的参数查询并删除
        dishMapper.deleteBatchIds(ids);
        //删除口味
        LambdaQueryWrapper<DishFlavor> dqw = new LambdaQueryWrapper<>();
        //通过菜品id查询关联口味id
        dqw.in(DishFlavor::getDishId, ids);
        //删除关联口味
        dishFlavorMapper.delete(dqw);
        //清除该菜品相关的缓存
        Set dishKeys = redisTemplate.keys("dish:*");//读取所有key
        redisTemplate.delete(dishKeys);//批量删除
    }

    //新增套餐回显
    @Override
    public List<Dish> findByType(Long categoryId, String name) {
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        //通过传入的名称查找菜品name
        qw.like(StrUtil.isNotEmpty(name), Dish::getName, name);
        //通过传入的ID参数查找菜品分类id
        qw.eq(categoryId != null, Dish::getCategoryId, categoryId);
        //使用mapper层方法遍历找到的id数据并回先数据
        return dishMapper.selectList(qw);
    }

    //根据分类id+状态查询菜品列表
//    @Override
//    public List<Dish> findList(Long categoryId, Integer status) {
//        //查询菜品列表        select * from dish where category_id = ? and status = ?
//        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
//        qw.eq(Dish::getCategoryId, categoryId);//根据分类id查询分类
//        qw.eq(Dish::getStatus, status);//查看是否起售
//        //查询遍历所有分类
//        List<Dish> dishList = dishMapper.selectList(qw);
//        //遍历菜品
//        for (Dish dish : dishList) {
//            //根据菜品id查询口味
//            LambdaQueryWrapper<DishFlavor> dqw = new LambdaQueryWrapper<>();
//            dqw.eq(DishFlavor::getDishId, dish.getId());//根据菜品id查询到菜品
//            //遍历所有口味
//            List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(dqw);
//            //将口味封装到菜品中
//            dish.setFlavors(dishFlavors);
//
//        }
//        //返回结果
//        return dishList;
//    }
    //h5根据分类id+状态查询菜品列表
    public List<Dish> findList(Long categoryId, Integer status){
        //返回声明对象
        List<Dish> dishList = null;

        //先查询缓存
        String disKey = "dish:"+categoryId;
        dishList = (List<Dish>) redisTemplate.opsForValue().get(disKey);//查询是否有数据
        //如果有则直接返回结果
        if (dishList != null){
            log.info("从redis中查询数据");
            return dishList;//返回查询到的结果
        }else {//如果没有直接从数据库调取
            log.info("从数据库中查询数据");
            //查询菜品列表
            LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
            qw.eq(Dish::getCategoryId,categoryId);//根据传入的id查询数据库中菜品id
            qw.eq(Dish::getStatus,status);//查询状态
            //mapper层方法查询菜品
            dishList = dishMapper.selectList(qw);
            //遍历菜品
            for (Dish dish : dishList) {
                //根据菜品查询口味
                LambdaQueryWrapper<DishFlavor> dqw = new LambdaQueryWrapper<>();
                dqw.eq(DishFlavor::getDishId,dish.getId());//根据菜品id查询关联口味
                List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(dqw);//查询菜品
                dish.setFlavors(dishFlavors);//封装到菜品
            }
            //将封装数据同步到redis中
            redisTemplate.opsForValue().set(disKey,dishList);
            return dishList;
        }
    }

}



